package tablaSimbolos;

import java.util.HashMap;
import java.util.Set;

import utils.Clase;
import utils.Tipo;

class TablaSimbolos {

	private HashMap<String, Tupla> ts;

	public TablaSimbolos() {
		ts = new HashMap<String, Tupla>();
	}

	public TablaSimbolos(HashMap<String, Tupla> ts) {
		setTS(ts);
	}

	public HashMap<String, Tupla> getTS() {
		return ts;
	}

	public void setTS(HashMap<String, Tupla> ts) {
		this.ts = ts;
	}

	public void addSymbol(String iden, Clase clase, Tipo Tipo, Integer dir) {
		ts.put(iden, new Tupla(clase, dir, Tipo));
	}

	public Clase getClase(String id) {
		if (ts.containsKey(id)) {
			return ts.get(id).getClase();
		} else {
			return null;
		}
	}

	public void setClase(String id, Clase clase) {
		ts.get(id).setClase(clase);
	}

	public Tipo getTipo(String id) {
		if (ts.containsKey(id)) {
			return ts.get(id).getTipo();
		} else {
			return null;
		}
	}

	public void setTipo(String id, Tipo Tipo) {
		ts.get(id).setTipo(Tipo);
	}

	public Integer getDir(String id) {
		if (ts.containsKey(id)) {
			return ts.get(id).getDir();
		} else {
			return null;
		}
	}

	public void setDir(String id, Integer dir) {
		ts.get(id).setDir(dir);
	}

	public Tupla get(String id) {
		return ts.get(id);
	}

	public boolean containsKey(Object o) {
		if (o == null || !(o instanceof String)) {
			return false;
		} else {
			return ts.containsKey((String) o);
		}
	}
	
	public Tupla put(String key, Tupla value) {
		return ts.put(key, value);
	}

	public String toString() {
		return ts.toString();
	}
	
	public Object clone() {
		TablaSimbolos tabla = new TablaSimbolos();
		Set<String> keys = ts.keySet();
		for (String key : keys) {
			tabla.put(key, (Tupla) ts.get(key).clone());
		}
		return tabla;
	}

	private class Tupla {

		private Clase clase;
		private Integer dir;
		private Tipo tipo;

		private Tupla(Clase clase, Integer dir, Tipo tipo) {
			this.clase = clase;
			this.dir = dir;
			this.tipo = (Tipo) tipo.clone();
		}

		private Clase getClase() {
			return clase;
		}

		private void setClase(Clase clase) {
			this.clase = clase;
		}

		private Integer getDir() {
			return dir;
		}

		private void setDir(Integer dir) {
			this.dir = dir;
		}

		private Tipo getTipo() {
			return tipo;
		}

		private void setTipo(Tipo tipo) {
			this.tipo = tipo;
		}

		public String toString() {
			return "<clase: " + clase + ", dir: " + dir + ", tipo: " + tipo
					+ ">";
		}
		
		public Object clone() {
			return new Tupla(clase, dir, (Tipo) tipo.clone());
		}
	}

}
